#include "UartTask.h"
 
xQueueHandle UARTQueue;
xTimerHandle UARTtimer;
LPC_UART_TypeDef *UARTx;
Comms_Msg_Struct *rxMsg;
Comms_Msg_Struct cms;
Comms_Msg_Struct *txMsg;
uint32_t UARTLength;
uint8_t UARTrxbuf[sizeof(Comms_Msg_Struct)];
uint8_t UARTtxbuf[sizeof(Comms_Msg_Struct)];

extern xQueueHandle DataManagerThreadQueue;
unsigned int startUART = 0;
								

void UARTTaskCode( void * pvParameters ){
	
	// initialize UART
	init_UART();
	txMsg = &cms;

	// Go to infinite Loop
	for(;;)
	{	
		//UART out of ARM
		if( UARTQueue != 0 )
		{
			if( xQueueReceive( UARTQueue, (void*)&rxMsg, ( portTickType ) 0 ) ) 
			{ 	
				if(rxMsg->msgType == Web || rxMsg->msgType == Command)
				{
					startUART = rxMsg->data[0];
				 	if(rxMsg->data[0] == 0)
				 		SendStop();
				}
				else
				{
					SendUARTMsg(rxMsg);
				} 
			}
		}

		if(startUART == 1)
		{
			//Received UART Msg to DataManagerThread
			uint8_t start = UART_ReceiveByte(UARTx);
			if (start==0x55) 
			{
				UARTLength = UART_Receive(UARTx, UARTrxbuf, sizeof(Comms_Msg_Struct), BLOCKING);
				if (UARTLength == 9) 
				{
					if( DataManagerThreadQueue != 0 )
					{
						txMsg->msgType = UARTrxbuf[0];
						txMsg->counter = UARTrxbuf[1];
						txMsg->size = UARTrxbuf[2];
						txMsg->data[0] = UARTrxbuf[3];
						txMsg->data[1] = UARTrxbuf[4];
						txMsg->data[2] = UARTrxbuf[5];
						txMsg->data[3] = UARTrxbuf[6];
						txMsg->data[4] = UARTrxbuf[7];
						txMsg->data[5] = UARTrxbuf[8];
						if(xQueueSend( DataManagerThreadQueue, (void * ) &txMsg, ( portTickType ) 0 ) != pdPASS){};
					}
				}		
			}
		}
		else
			continue;			
	}
}
 

void Init_UART_Task()
{
	xTaskHandle UARTHandle;
  	xTaskCreate( UARTTaskCode, ( signed char * ) "UART Task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY
  	, &UARTHandle );
  	UARTQueue = xQueueCreate( 100, sizeof(Comms_Msg_Struct *)  );
}

void SendUARTMsg(Comms_Msg_Struct* Msg) 
{ 	
	UART_SendByte(UARTx, 0x80);
	UARTtxbuf[0] = Msg->msgType;
	UARTtxbuf[1] = Msg->counter;
	UARTtxbuf[2] = Msg->size;
	UARTtxbuf[3] = Msg->data[0];
	UARTtxbuf[4] = Msg->data[1];
	UARTtxbuf[5] = Msg->data[2];
	UARTtxbuf[6] = Msg->data[3];
	UARTtxbuf[7] = Msg->data[4];
	UARTtxbuf[8] = Msg->data[5];
	UART_Send(UARTx, UARTtxbuf, 9, BLOCKING);
}

void SendStop()
{
	UART_SendByte(UARTx, 0x80);
	UARTtxbuf[0] = 0x04;
	UARTtxbuf[1] = 0x00;
	UARTtxbuf[2] = 0x02;
	UARTtxbuf[3] = 0x40;
	UARTtxbuf[4] = 0xC0;
	UARTtxbuf[5] = 0x5;
	UARTtxbuf[6] = 0x6;
	UARTtxbuf[7] = 0x7;
	UARTtxbuf[8] = 0x8;
	UART_Send(UARTx, UARTtxbuf, 9, BLOCKING);
}

void init_UART()
{

        UARTx = (LPC_UART_TypeDef *)LPC_UART1;

        /* UART Configuration structure variable */
        UART_CFG_Type UARTConfigStruct;
        /* UART FIFO configuration Struct variable */
        UART_FIFO_CFG_Type UARTFIFOConfigStruct;
        /* Pin configuration for UART0 */
        PINSEL_CFG_Type PinCfg;

        if((uint32_t)UARTx == (uint32_t)LPC_UART0) {
                /*
                 * Initialize UART0 pin connect
                 */
                PinCfg.Funcnum = 1;
                PinCfg.OpenDrain = 0;
                PinCfg.Pinmode = 0;
                PinCfg.Pinnum = 2;
                PinCfg.Portnum = 0;
                PINSEL_ConfigPin(&PinCfg);
                PinCfg.Pinnum = 3;
                PINSEL_ConfigPin(&PinCfg);
        }
        else if ((uint32_t)UARTx == (uint32_t)LPC_UART1) {
                /*
                 * Initialize UART1 pin connect
                 */
                PinCfg.Funcnum = 2;
                PinCfg.OpenDrain = 0;
                PinCfg.Pinmode = 0;
                PinCfg.Pinnum = 0;
                PinCfg.Portnum = 2;
                PINSEL_ConfigPin(&PinCfg);
                PinCfg.Pinnum = 1;
                PINSEL_ConfigPin(&PinCfg);
        }

        /* Initialize UART Configuration parameter structure to default state:
         * Baudrate = 9600bps
         * 8 data bit
         * 1 Stop bit
         * None parity
         */
        UART_ConfigStructInit(&UARTConfigStruct);
		//UARTConfigStruct.Parity = UART_PARITY_SP_1;
		//UARTConfigStruct.Stopbits = UART_STOPBIT_1;
		//UARTConfigStruct.Databits = UART_DATABIT_8;

        /* Set Baudrate to 19200 */
        UARTConfigStruct.Baud_rate = 9600;

        /* Initialize UART0 peripheral with given to corresponding parameter */
        UART_Init(UARTx, &UARTConfigStruct);

        /* Initialize FIFOConfigStruct to default state:
         *                              - FIFO_DMAMode = DISABLE
         *                              - FIFO_Level = UART_FIFO_TRGLEV0
         *                              - FIFO_ResetRxBuf = ENABLE
         *                              - FIFO_ResetTxBuf = ENABLE
         *                              - FIFO_State = ENABLE
         */
        UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
		
        /* Initialize FIFO for UART0 peripheral */
        UART_FIFOConfig(UARTx, &UARTFIFOConfigStruct);

        /*  Enable UART Transmit */
        UART_TxCmd(UARTx, ENABLE);
}